Data Structures

Arrays
Arrays are homogeneous structures.
An array is something that you can stick a lot of different things into, but all of them must be the same type.
An array is a group of things that are together because they are the same type not necessarily the same value.

Arrays
An example
Let us consider an array of social security numbers. Let picture of the disk represents each of the numbers:
<data type> <array name>[<size>];
int SSN[5];
SSN[1] = 345;

Arrays
Declaration
An array is a collection of variables of the same type. Individual array elements are identified by an integer index. In C the index begins at zero and is always written inside square brackets.
int results[20];
int results_2d[20][5];
int results_3d[20][5][3];

Arrays
Initialisation

Declarations of arrays (Cont.)
Pascal C/C++
var
a: array[0..9] of integer;
b: array[0..4, 0..9] of integer;
int a[10];
float b[5][10];
Arrays in C always have subscripts ranging from 0 to declared size – 1.

Arrays
An Example
#include <iostream.h>
int main() {
int x, y, anarray[8][8];//declares an array like a chessboard
for(x=0; x<8; x++) { // sets the element to
for(y=0; y<8; y++) { // zero; after the loop all
anarray[x][y]=0; // elements == 0
    } }
for(x=0; x<8;x++) {
for(y=0; y<8; y++) { cout<<"anarray["<<x<<"]["<<y<<"]="<<anarray[x][y]<<" ";
} }
return 0;
}

Arrays and functions
An Example
int add_array(int array[], int size)
      {
int i;
int total = 0;
for (i=0; i < size; i++)
total += array[i];
return(total);
}

Arrays:
Things to remember
An array identifier is a constant pointer.
Arrays are stored by rows.
Let AnArray be a 2-dimensional array of type type.
The type of AnArray is a pointer to a row.
The type of *AnArray is a pointer to type.
In the expression AnArray+i, i is scaled by the size of the row.
In the expression *AnArray+i, i is scaled by the size of type.
*AnArray = AnArray[0]
**AnArray = *(AnArray[0]) = AnArray[0][0]
AnArray[i] = *(AnArray+i) = *AnArray + i* number of columns

Arrays:
Things to remember
If AnArray is a single-dimensional array of type type passed as parameter to a function, AnArray may be declared as
type AnArray[];
The size of AnArray may be specified, but it is neglected.
type * AnArray;
If AnArray is 2-dimensional array of type passed as parameter to a function, AnArray may be declared as
type AnArray[][size2];
And the specification of the constant size2 must not be omitted.

Pointers
Pointers are data types.
They store memory addresses of variables.

Pointers:
Definition
The pointer is like any other variable except that the value stored in it has a different interpretation: It is the address of some memory location.
Pointer is variable that holds a memory address

Pointer:
Interpretation
ThePointer is defined as a variable of the type pointer to integer, or simply, pointer. Assume value 5FA62 is stored in ThePointer. This value is interpreted as a memory address.
If the contents of memory location 5FA62 is 658, then the value of ThePointer is 5FA62 and ThePointer points to the value 658.
Sometimes the address stored in a pointer is not important, so the following abbreviation can be used:

Pointer:
Dereferencing mechanism
Since the value stored in a pointer is a memory address, the language has to provide a dereferencing mechanism: the mechanism that can be used to access the value pointed to by the pointer. &px has the value 654.
& is called the address operator.

Dereferencing pointers and the address operator
Dereferencing refers to accessing the value that a pointer points to.
To do this “*” operator that interprets single argument as an address and returns the contents of the address as the value of the operation. Usage:
*p
EXAMPLE:
int i = 25, *j;
Here, j is a pointer to integer. Assume i and j are allocated memory cells at addresses 5FA62 and 5FA70, respectively. This means that the value of i is 25, &i is 5FA62 and the value of &j is 5FA70.

Pointer:
Accessing data
The initial value of a variable, including a pointer variable, is undetermined. Let assume that the initial value stored in p is 5FA62:

Pointer:
Accessing data
The initial value of a variable, including a pointer variable, is undetermined. Let assume that the initial value stored in p is 5FA62:

Pointer Assignment Ex.5300

Pointerst Test yourself
#include <iostream.h>
int main()
{
int x; //A normal integer
int *pointer; //A pointer to an integer
pointer=&x; //Read it,
//"pointer equals the address of x“
cin>>x; //Reads in x
cout<<*pointer; //Note the use of the * to // output the actual number stored in x
return 0;
}

Pointers
Pascal C/C++
var
p: ^integer;
first: ^student;
struct student *first;

Pointers (Cont.)
Pascal C/C++
type
stuptr = ^node;
var
  first: stuptr;
typedef
struct student *stuptr;
stuptr first;

The NULL pointer
The special value NULL can be assigned to the pointer to indicate that its value is defined but that it does not point to anything.
The NULL is usually equal to 0.
A convenient way to set the initial value of a pointer to NULL is in the definition itself:
int *pi = NULL, *pj = NULL;

Dynamic memory allocation
In C++, the new and delete operators provide build-in language support for dynamic memory allocation and deallocation.
This feature has several benefits:
Reduces common programmer errors: it is easy to forget to multiply the number of objects being allocated by sizeof when using malloc.
Enhances source code clarity: generally, there is no need to: (1) declare operator new and delete, (2) explicitly use casts, or (3) explicitly check the return value.
Improves run-time efficiency: (1) users can redefine operator new and delete globally and also define then on a per-class basis and (2) calls can be inlined.

new() operator
The keyword new is used to initialise pointers with memory from free store (a section of memory available to all programs).
int *ptr = new int;
It initialises ptr to point to a memory address of size int (because variables have different sizes, number of bytes, this is necessary). The memory that is pointed to becomes unavailable to other programs. This means that the careful coder will free this memory at the end of its usage.

delete() operator
The delete operator frees up the memory allocated through new. To do so, the syntax is as in the example.

delete ptr;

After deleting a pointer, it can be a good idea to reset it to point to NULL.
NULL is a standard compiler-defined statement that sets the pointer to point to, literally, nothing. By doing this, you minimise the potential for doing something foolish with the pointer.

new() and delete()
Example
int main() {
}

new() and delete()
Some remarks
new returns a pointer to the allocated memory
The storage duration of the new object is from the point of creation until the operator delete destroys it by deallocating its memory, or until the end of the program.
By default, an allocation failure (such as insufficient or fragmented heap memory) results in the predefined exception bad_alloc being thrown.
You should use the delete operator to remove all memory which has been allocated by the new operator. Failure to free memory can result in memory leaks.
The delete operator offers dynamic storage deallocation, deallocating a memory block allocated by a previous call to new.

Example: allocate 2D array, initialise and delete it.
#include <iostream.h>
void display(long double **);
void de_allocate(long double **);
int NumRows = 3;
int NumCols = 5;
void display(long double **data) {
   for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++)
             cout << data[i][j] << " ";
       cout << "\n" << endl;
       }
   }

Example: allocate 2D array, initialise and delete it.
void de_allocate(long double **data) {
   for (int i = 0; i < NumRows;  i++)
       delete[] data[i]; // STEP 1: delete the columns
   delete[] data;  // STEP 2: delete the rows
   }
void initialise(long double ** data){
for (int i = 0; i < NumRows; i++)
      for (int j = 0; j < NumCols; j++)
         data[i][j] = i + j;   // arbitrary initialisation
}

Example: allocate 2D array, initialise and delete it.
int main(void) {
   long double **data;
   data = new long double*[NumRows];                                   // STEP 1: SET UP THE ROWS.
      for (int j = 0; j < NumRows; j++)
          data[j] = new long double[NumCols];
                                // STEP 2: SET UP THE COLUMNS
   initialise(data);
   display(data);
   de_allocate(data);
   return 0;
   }

Arrays  and Pointers
One thing that arrays don't require that other variables do, is a reference operator when you want to have a pointer to the string.
EXAMPLE:
//As opposed to

Arrays  and Pointers
The array can be initialised using pointers as follows.
ArrayExample = new int[25];
which allows to access ArrayExample just as if it were an array. Keep in mind that to use delete you must put [] between delete and ArrayExample to tell it to free all 25 bytes of memory allocated.

delete [] ArrayExample;

The heap
The new routine reserves a block of memory of the requested size in a pool of free memory called the heap.
Two separate data storage areas are used by the program during run time: the stack and the heap.
The lifetime of data stored on the stack is relative to the lifetime of the subroutine that the data are defined in.
The lifetime of data stored in the heap starts with the execution of the allocation procedure new and ends when the deallocation procedure delete is called.

heap operations
Advanced
Works with vectors
A heap is a binary tree in which every node is larger than the values associated with either child. A heap and a binary tree, for that matter, can be very efficiently stored in a vector, by placing the children of node i in positions 2 * i + 1 and 2 * i + 2.
Using this encoding, the largest value in the heap is always located in the initial position, and can therefore be very efficiently retrieved.

heap operations
Advanced
Works with vectors
A heap is a binary tree in which every node is larger than the values associated with either child. A heap and a binary tree, for that matter, can be very efficiently stored in a vector, by placing the children of node i in positions 2 * i + 1 and 2 * i + 2.
Using this encoding, the largest value in the heap is always located in the initial position, and can therefore be very efficiently retrieved.

heap operations
Advanced
A heap is a particular organization of elements in a range between two random access iterators [a, b). Its two key properties are:
1. *a is the largest element in the range.
2. *a may be removed by the pop_heap algorithm, or a new element can be added by the push_heap
 algorithm, in O(logN) time.
These properties make heaps useful as priority queues.
The heap algorithms use less than (operator<) as the default comparison. In all of the algorithms, an alternate comparison operator can be specified.

Pointers:
Things to remember
Pointers are NOT integers.
Always to test whether or not memory allocation requests are successful.
Only memory that has been allocated using new (or the related routines) should be freed using delete operator.
To pass a parameter by variable, specify this parameter that is a pointer, use a pointer to pointer.
Always cast the NULL pointer when it is passed as an actual parameter.
Do not declare pointer as a global variable.

Glossary
Allocation of memory The action of acquiring a block of memory from the heap.
Deallocation of memory The action of returning a block of memory to the heap.
Dereferencing of a pointer’s value The value pointed to by a pointer.
Heap A pool of free memory. Dynamic memory requires allocate memory from this area.
Pointer A variable whose value is interpreted as a memory address. A pointer points to the value stored in the location at that address.

Structures
Declaration
Structure type
Structure variable

Structures
Declaration: Example (Step 1)
Structure type
Structure variable

Structures
Declaration: Example (Step 2)
Structure type
Structure variable

Structures
Declaration: Example (Step 3)
Structure type
Structure variable

Structures
Declaration: Example (Step 4)
Structure type
Structure variable

Structures
Initialisation Test yourself
A C structure variable may be initialised when it is declared.

Structures and Arrays
Initialisation
A C structure variable may be initialised when it is declared – e.g.

Structures
Example 1: Declaration

Structures and Pointers
Declaration
Declaration of pointers to structures:
This defines John as a structure and pJohn as a pointer to a structure.
pJohn variable initialisation:
pJohn can be made to point to John:
pJohn = &John;
new can be used to allocation memory for pJohn:
int *pJohn = new student;

Structures and Pointers
Access to data
The first attempt to access the fields of the structure John through pJohn can be:
(*pJohn).StudentID;
An alternative way:
pJohn->StudentID;

Structures and Pointers
Example 2: Access to data
#include <iostream.h>
struct example { int field1; int field2; };
int main()
{ example Structure;
example *PointerToStructure;
Structure.field1=12;
PointerToStructure =& Structure; //& is necessary when  dealing with structures and using pointers to them
cout<< PointerToStructure->field1; //The -> acts somewhat like the * when used with pointers. It says, get whatever is at that memory address Not "get what that memory address is"
return 0;
}

Structures and pointers
Example 3: Using two structures

Structures and pointers
Example 3: Using two structures

Structures and pointers
Example 3: Using two structures

Structures
Stack principle
NOTE: Each of the big blocks is a struct (or class) that has a pointer to another one. Remember that the pointer only stores the memory location of something, it is not that thing, so the arrow goes to the next one. At the end, there is nothing for the pointer to point to, so it does not point to anything, it should be set to "NULL" to prevent it from accidentally pointing to a totally arbitrary and random location in memory (which is very bad).

Structures
Example 3: Stack
struct node {
int value;
node *next;
};
int main() {
node *root; This will be the unchanging 1st node
root=new node; Now root points to a node struct
root->next=NULL; //The node root points to has its
// next pointer set equal to NULL
root->value=5; // By using the -> operator, you
// can modify the node
return 0; //a struct (root in this case) points to.
}

Stack
Example 4
int main() {
//This won't change, or we would lose the list in memory
//This will point to each node as it traverses the list
//Sets it to actually point to something
//Otherwise it would not work well
//The conductor points to the first node
// Creates a node at the end of the list
//Points to that node
//Prevents it from going any further
}

Structures
Traversal function
conductor=root;
// Makes sure there is a place to start
if(conductor!=NULL) {
while(conductor->next!=NULL) {
cout<<conductor->x;
conductor=conductor->next;
}
cout<<conductor->x;
}

Construct a list
 Example (Step 1)

Construct a list
Example (Step 2)

Construct a list
Example (Step 3)

Construct a list
Example (Step 4)

Structures and Functions
Functions may return pointers to structures, and they may have parameters that are pointers to structures.
A function may return a structure, and structures may be passed as parameters.

Structures and Functions
Example Test yourself
 TASK: The program discussed shows 2 functions: *new() and new1 that create a new object for the structure

Structures
Pascal C/C++
var
student: record
id: integer;
name: packed array[1..10] of char;
gpa: real
end;
struct
{ int id;
  char name[11];
  float gpa;
} student;

Structures (Cont.)
Pascal C/C++
var
borrower: record
case boolean of
false: (EBorr: emploee);
true: (SBorr: student)
end;
union
{   emploee EBorr;
     student SBorr;
} borrower;

Structures (Cont.)
Pascal C/C++
var
borrower: record
case IsStudent of
false: (EBorr: emploee);
true: (SBorr: student)
end;
NO DIRECT EQUIVALENT IN C. THIS CAN BE HANDLED BY CREATING A STRUCT WHICH CONTAINS THE TAG AND A UNION AS ITS FIELDS. (SEE NEXT SLIDE)

Structures (Cont.)
Pascal C/C++
var
borrower: record
id: integer;
name: packed array[1..10] of char;
case boolean of
false: (EBorr: emploee);
true: (SBorr: student)
end;
struct
{    int id;
     char name[11];
     union
     {   emploee EBorr;
         student SBorr;
      } Borr;
} borrower;

Structures: Initialisation
Pascal C/C++
NO STANDARD PASCAL EQUIVALENT (BUT MANY DIALECTS ALLOW THIS)
A C variable may be initialised when it is declared – e.g.
int i = 3;
char c = ‘A’;
float a[3] = {1.0, 2.0, 3.0};
struct
{ char name[11];
   float gpa;
} student = {“Smith”, 4.0};

Structures
Common errors

Structures
Things to remember
Structures are stored in blocks of consecutive memory locations with padding if memory alignment is required.
Structure assignments and passing a structure as a parameter involves copying the entire structure.
C does not permit self-referential structure definitions:

Structures and Pointers
Things to remember
Attempts to access the fields of the structure John through PointerJohn that is defined as
PointerJohn = &John;.
‘.’ has higher precedence than *, so the expression
would be interpreted as:
The following expression is get out of the problem:
As an alternative notation that is equivalent to the preceding expression is: